      Help File for DataSuite
      =======================

  DataSuite is not an application per se but is in fact a central resource
application for the all applications using the DataSuite system of modules.
The original idea for the resource application was by Julian Wright with minor
sprite improvements by Philip R. Banks. The modules are all accesable by a new
path - the DataSuite: path. All applications intending to use the modules
should use this path to access them if need be.

   After having 'seen' this application you should be able to play most
samples simply by double clicking on them. DataVox, Armadeus and DSEdit
samples are all catered for. Furthermore a public area filtype, &FF, has been
assigned to become 'un-typed' sound files that don't have file-types but do
have enough header information to allow them to be played.

  The DataSuite set of modules is all code by P.R.Banks who can be contacted
at :-

                  10 Southgate Rd,
                  Island Bay,
                  Wellington,
                  New Zealand.

If you have any queries. Also included in with this application are the
documentation files for the DataSuite Modules which are the powerhouse
behind the application. These are located inside this application in the sub
directory `Docs`.

   The DataVox, DataLoad, DataPatch and DataPlay modules are supplied as
FreeWare. You may use these modules for any non-commercial program you care
to. If you wish to use them in a commercial release then you must obtain my
permision. Why am I releasing these modules as FreeWare? Because these
modules make the use of the sound system much much easier as well as
providing alot of much needed facilities that are currently missing. All I
ask is that in any non-commercial release that you credit me for the use of
the sound modules. Of course a copy of the program would be nice too but it
is optional.

   Any other modules present in the DataSuite directory are not FreeWare but
are copyright to me and may *not* be distributed. Any applications that
need these extra modules will have them supplied with it.

 N.B. I do not take any responsibility for any damage or loss caused by
        the use or misuse of this software in any way shape or form.



 DataVox Help File.
 ==================

 NB If you are using this module under Risc OS kernel version 2.00 then you
    must have IRQutils module v0.9 or greater loaded! This is because
    DataVox makes heavy usage of transient call backs and the 2.00 kernel
    routines have an error in them that IRQutils fixes. Failure to load
    this module can result in address exceptions and your machine crashing!

   This module will play chunks of memory through the sound system with the
 emphasis on being able to customise dynamically how it plays. It provides
 several SWI's and * commands for it's control. It is to be noted that
 while the voice can handle a large variety of types of data it cannot
 handle 16 bit data *only* 8 bit data. If demand is high enough I will
 update this module to handle 16 bit data but it will increase its size
 somewhat dramatically! (Which is why I have not included it...)
   The newest feature of this module is complete system speed independance
 of playing of sounds. Code has been written into this module to ensure
 that it will always *attempt* to play a sound at its correct pitch no
 matter what the system speed (in micro seconds) is set to. Due to hardware
 and software limitations this will not always sound terribly good but at
 least it tries. This means your sample set to play nicely at the default
 48 micro seconds (20.833 kHz) will still sound fine when a sound tracker
 is playing, which bumps the system speed up to 34 micro seconds (29.411
 kHz). As far as I am aware this is the first ever module on the Arc to
 attempt this.
   To use this module you use the SWI "DataVox_SetMemory" to set a channel
 up for playing and issue sound commands after setting the appropriate 
 data type using SWI "DataVox_Type". Easy eh? Nope? Well that is why I 
 have bundled this module with its companion 'DataLoad' which provides
 a nice OSCLI command interface for convienance. See the file DtLdHelp
 for more information.

 The Concepts of DataVox
 =======================

   DataVox is a module exclusively designed to play chunks of memory
 through the sound system of the Arc. DataVox has no concept of files
 or *anything* other than memory when it comes to playing and it has
 been heavily geared towards this. The abstraction of files and loading/
 saving of them etc.. has been kept away from DataVox for two reasons :-

 Size - Every effort has been made to keep DataVox as small as possible
      while still retaining a friendly user interface. The other side
      effect is that it helps to keep DataVox as fast as possible.

 Flexibility - Because DataVox has no concept of files etc... an application
      can, with very little effort, bend DataVox to play files in any
      manner it sees fit. This allows applications to do things like
      playing compressed samples,playing from disk or just plain having
      all the sound data to be played memory resident.

 As you can see this leaves DataVox a very flexible module, part of what
 I set out to do with it.
   The sound system provided on the Arc has two major concepts in it. That
 of a channel and of a voice. DataVox provides a sound system *voice* that
 provides an extra layer to the *channel* system. DataVox's voice allows
 you to play differing things depending on what sound system channel is
 attached to it and to this end provides it's own internal channel system.
 A DataVox channel is a channel internal to DataVox and must not be confused
 with a sound system channel.
   Each DataVox channel is fully independant of all the other DataVox
 channels and there is a direct one-to-one correspondence between DataVox
 channels and sound system channels. That is from the sound system only
 Operating System sound channel 1 can, when assigned to the DataVox Voice,
 access DataVox channel 1, also OS channel 2 can only access DataVox channel
 2,etc.... The layering goes something like this :-

  OS sound channels -----> Voices
  (of which there are      WaveSynth-Beep
   eight)                  ...
                           Percussion-Noise
                           DataVox-Voice ------> DataVox channels
                                                 (of which there are eight-
                                                 to allow a 1-1 matching
                                                 with the OS channels)

  Each DataVox channel has information about what memory it is to play etc..
  and these settings apply only to that one channel. Some of this infor-
  mation is set out below.

  Channel Timed Pitched Type   Start     End       Rpt Start Rpt End   Rvse  
     1     No    No      Log   &00000000 &00000000 &00000000 &00000000 No

 This is  Does  Does it The    The start The end   The start The end   Does
 DataVox  it    use     Type   address   address   address   address   it
 channel  play  fixed   of     in memory in memory in memory in memory play
 and its  in    pitch   Data   of what   of what   of where  of where  the
 `master' timed play?   to     to play.  to play.  to begin  to end    Data
 channel. mode?         Play.                      repeating repeating Back-
                                                   play of   play of   wards?
                                                   the Data. the Data.

   Rate
   &00

 The rate
 in micro-
 seconds 
 the Data
 is played
 at.

 All of the settings listed above are reported to you by the *DataVoxStatus
 command. Also stored about each channel is a key for multi-tasking access
 , an address for UpCall code associated with the channel, where the voice
 is up to in memory if the channel is playing & a toggling flag to indicate
 which buffer is in use. For more details about precisely what all these
 flags etc.. mean see the SWI command explanations.
   The various SWI's provided can be divided into several groups based on
 what there general function is. These groups are :-

 Setting Channel Data   - DataVox_Type
                          DataVox_Timed
                          DataVox_Pitch
                          DataVox_SetMemory
                          DataVox_SetRepeat
                          DataVox_SetReverse
                          DataVox_UpCallHandler
                          DataVox_SlaveChannel
                          DataVox_AdjustMemory

 These SWIs are how applications set the DataVox channel settings.

 Reading Channel Data   - DataVox_ReadType
                          DataVox_ReadTimer
                          DataVox_ReadPitch
                          DataVox_ReadMemory
                          DataVox_Repeat
                          DataVox_ReadReverse
                          DataVox_ReadMaster
  
 These SWIs are how applications read what the DataVox channel settings 
 currently are.

 Monitoring Channels    - DataVox_ReadAddress
                          DataVox_ReadBufferFlag

 These SWIs provide the means by which applications can do real time
 monitoring of the play of data.

 Reading DataVox Status - DataVox_VoiceActive
                          DataVox_SystemSpeed
                          DataVox_Version

 These SWIs provide general status information about DataVox.

 Mulitasking Support    - DataVox_AllocateChannel
                          DataVox_DeAllocateChannel
                          DataVox_RequestChannel
                          DataVox_ChannelsFree
                          DataVox_ChannelFreeMap

 These SWIs provide the multi-tasking support of DataVox for applications
 and should *always* be used by an application. See the section `Multi-
 Tasking and DataVox' for more details.

 Application Support    - DataVox_PitchToSample
                          DataVox_SampleToPitch
                          DataVox_Duplicate
                          DataVox_Unset
                          DataVox_ConvertByte
                          DataVox_ConvertArea

 And these SWIs provide application support to allow an application to
 make use of the system speed independance of DataVox and to generally
 make an applications life easier.
   Okay and that about wraps up all the essential concepts of DataVox.
 The whole idea of DataVox is to provide a consistant,multi-tasking
 & highly flexible system of playing sound data on the Arc. Hopefully
 the information I have given you here and a good reading of what is
 presented below will allow you to make full use of the power of DataVox.

 Multi-Tasking and DataVox
 =========================

   This module has a set of four SWI's built into it to allow easy and
 smooth multitasking use of itself. These SWI's are AllocateChannel,
 DeAllocateChannel,RequestChannel & ChannelsFree. Three of them require
 the passing of a `Unique Key' to them. All this is is a 32 bit number of
 some kind that is used to provide a measure of allocation security. This
 ,when used wisely, allows an application to claim and use a channel happy
 in the knowledge that it is the only `official' user of that channel.
 It is recommended that the task handle number given to an application
 by the Wimp be used as the key as this will be unique to that particular
 instantation of the application. Of course if you have good reason not
 to use the task handle number then any number will suffice.
   However while an application can be reasonably secure in the knowledge
 that once it has been allocated a channel it is the only application that
 will `officially' own it, no such claims can be made on the settings of
 the channel. This is due to maintaining backwards compatability and
 problems with channel ownership by loader modules. The consequence of
 this is that an application must check the settings before each use of
 the channel. The exact strategy used will vary from application to
 application.
   The recommended procedure for applications using DataVox is as follows.

 For `fixed voice no.' applications :-

   START
     |
   Verify Sufficient channels are free for use.
   Claim these channels.
     |
   Verify channel Settings---+
   Use channel               |
     |                       |
     +-Loop as required------+
     |
   Deallocate the claimed channels
     |
    END

 For `dynamic voice no.' applications :-

   START
     |
   Verify Sufficient channels are free.--+
   Claim these channels                  |
   Use said channels                     |
   Release these channels                |
     |                                   |
     +-Loop as required------------------+
     |
    END

  As can be seen the only major difference between the two application
  stratageys is when the voices are claimed and released. These minor
  shifts in place require radically different error handling and coding
  however as the dynamic voice application can never make any assumptions
  as to whether sufficient channels will be available for it to use at
  any given time. Both of these stratageys ensure that the application
  verifies the channels settings before use thus catering for possible
  interference with these settings between wimp polls.
    How often tasks need to verify that their channels are set correctly
  will vary according to what the task does. Two main strategys spring
  to mind 1) Check the settings every Wimp_Poll and reset them as needed.
  2) Check the settings just before use is made of the channel (And
  not before). The second strategy is the prefered method as it requires
  less processor time to maintain.
    Finally some tasks will need a particular channel to operate properely
  and so the SWI RequestChannel has been provided. This allows an application
  to request for a particular channel rather than simply asking for one and
  getting any random channel back. Again the application will be turned down
  if they do not own the channel (if it is claimed) so applications must be
  prepared to cope with this.
    Other than these guidelines usage of the channel is up to the 
  application involved. Not following these guidlines is not a good idea
  as this can result in applications `squabbling' over channels with the
  unpredictable results that can result in. Also in no way will DataVox
  ensure that the Arc's Sound System has a sufficient number of channels
  active or that those channels are assigned to it. This is the
  applications responsibility as the way the Sound System handles channels
  may be revised in future releases of the OS. This way the module will
  automatically cope with the new OS...

  N.B. I am well aware that the security afforded by the key system is
  ridiculously simple to circumvent. It is not intended to provide a
  secure system but is merely intended as an aid to tasks to allow them
  to share the module in a consistent and easy manner. It is unlikely
  that I will extend the security system to allow security over channel
  settings, as this will destroy the backwards compatability the module
  has with old code, unless I receive sufficient comment from people to
  justify this alteration.

 OSCLI Commands
 ==============

 *DataVoxPitch
 This sets the fixed pitch of the data being played. Once this is set any 
 sound commands issued to this datachannel will be fixed at this pitch. To 
 return to normal pitching enter 0 as the pitch.
 Syntax *DataVoxPitch <DataChannel> <-&7FFF-&7FFF>.

 *DataVoxStatus
 This shows the status of the DataVox channels and their various parameters.
 Syntax *DataVoxStatus.

 *DataVoxTimer
 This sets whether the Voice Generator ignores the duration parameter of the
 SOUND command. Enter 0 for no timer control and 1 for timer control.
 Syntax *DataVoxTimer <DataChannel> <0|1>.

 *DataVoxType
 This sets the type of data being played. Enter 0 for Logarithmic (Archimedes
 native format),1 for Linear Unsigned (Macintosh & IBM), 2 for Linear Signed
 (Armadeus,Atari St & Amiga) and 3 for Ulaw logarithmic format (Sun).
 Syntax *DataVoxType <DataChannel> <0|1|2|3>.

 *DataVoxReverse
 This sets the direction of play. On (1) for reverse play & Off (0) for
 normal play.
 Syntax *DataVoxReverse <DataChannel> <0|1>.
  
 *DataVoxDuplicate
 This copies a DataChannel's settings across to another channel. This allows
 you to have several channels sharing the same piece of sound data easily.
 Note it is invalid to try and duplicate to the same channel number.
 Syntax *DataVoxDuplicate <Source DataChannel> <Destination DataChannel>.

 *DataVoxUnset
 This unsets a DataChannel, destroying all settings for that channel.
 Syntax *DataVoxUnset <DataChannel>.

 SWI Commands
 ============

   Here is the list of SWI commands provided by the DataVoxPlayer module.
 It is to be noted that when an error occurs R0 is always corrupted and not
 preserved as is indicated below. Also if you issue a SWI in the same chunk
 range as DataVoxPlayer but is an unrecognised SWI the error "Unknown 
 DataVox operation" will be returned. For all of these SWI's the interupt
 status is unchanged,the processor is in SVC mode and they are not 
 re-entrant. (Well actually some of them are but I haven't sorted out which
 are yet.)

 DataVox_Type
 On Entry:-
 R0 DataChannel
 R1 type to set it to
 On Exit:-
 R0 preserved
 R1 preserved
 Errors:-
 Bad Settype parameters.
 Use:- 
      This SWI sets the data type for the DataVox channel passed to it. R1
 should be 0 for logarithmic,1 for Linear Unsigned,2 for Linear Signed & 3 for
 Ulaw logarithmic. The new data typing will take effect at the next sound
 `start play' command.
 
 DataVox_Timed
 On Entry:-
 R0 DataChannel
 R1 On(1)/Off(0) flag
 On Exit:-
 R0 preserved
 R1 preserved
 Errors:-
 Bad Timer parameters.
 Use:-
      This sets whether the time parameter of a Sound command issued to the
 DataVox channel will be used or not. A Value of 1 will set it,0 will unset
 it.
 
 DataVox_Pitch
 On Entry:-
 R0 DataChannel 
 R1 Pitch
 On Exit:-
 R0 preserved
 R1 preserved
 Errors:-
 Bad Pitch parameters.
 Use:-
      This sets the fixed pitch of the sound channel. The values accepted
 are the same as those used by the *SOUND command for pitch, -&7FFF-&7FFF.
 Passing 0 in R1 turns the fixed pitching off and then the Voice responds
 to *SOUND commands the same as normal.

 DataVox_ReadPitch
 On Entry:-
 R0 DataChannel
 On Exit:-
 R0 preserved
 R1 Pitch on exit
 Errors:-
 Bad Read Pitch Channel.
 Use:-
      Not unsurprisingly this reads the pitch value for a channel. A value
 of zero indicates no fixed pitching,any other value is the fixed pitch.

 DataVox_ReadTimer
 On Entry:-
 R0 DataChannel
 On Exit:-
 R0 preserved
 R1 Timer Setting on exit
 Errors:-
 Bad Read Timer Channel.
 Use:-
      This returns the setting of the timer flag for a chanel. 0 means no
 timing and any non zero value indicates that timing will be used. This
 means that,when set,the timing parameter of *SOUND commands will be used.
 Otherwise the sound will play until it reaches the end of playable data.
 
 DataVox_ReadType
 On Entry:-
 R0 DataChannel
 On Exit:-
 R0 preserved
 R1 pitch of channel
 Errors:-
 Bad Read Type Channel.
 Use:-
      This returns the type of data to be played by a particular channel.
 A value of 0 indicates Logarithmic data,1 Linear Unsigned and 2 Linear
 Signed.
 
 DataVox_SetMemory
 On Entry:-
 R0 DataChannel
 R1 DataStart
 R2 DataEnd
 On Exit:-
 R0 preserved
 R1 preserved
 R2 preserved
 Errors:-
 Bad Set Memory parameters.
 Use:-
      This sets the chunk of memory that the channel will play. The only
 check that this call makes is that the memory end pointer is indeed larger
 than the memory start pointer. This means that any area in RAM can be played
 . This call also resets the channels type to Logarithmic,timer to off,
 reverse to off,the repeat section to be all of the sample & to normal 
 (unfixed) pitching. The voice fill code is in a privileged processor mode
 so *any* memory area can be played (Even the ROM space if you really want...
 :-) ). You must be careful to ensure that the memory to be played is always
 'there' when the voice generator needs it. This means that under the multi
 tasking Wimp you must not store voice data in application space *unless* you
 do not call Wimp_Poll until the sound has finished playing. Even then you
 must ensure that no sound commands will be issued to that channel while your
 application is paged out. If a sound request is received while the memory is
 paged out an address exception will occur and the voice generator will halt
 play in an undefined way. It can range from hanging the machine to merely 
 halting play! Of course if you *really* want to be a smart alec you can
 point it to physical memory which should always be there...but I don't 
 recommend it as I haven't tried it and thus can't be sure it will work.

 DataVox_ReadMemory
 On Entry:-
 R0 DataChannel
 On Exit:-
 R0 preserved
 R1 Start address of channel.
 R2 End addresses of channel.
 Errors:-
 Bad Read Memory Channel.
 Use:-
      This reads the memory start and end address of the specified channel.
 See DataVox_SetMemory for a more detailed account of what the results mean.

 DataVox_ReadAddress
 On Entry:-
 R0 DataChannel
 On Exit:-
 R0 preserved
 R1 current address.
 Errors:-
 Bad Read Address Channel.
 Use:-
      This reads the current absolute address that the voice is currently
 up to. If the voice is not playing at the time the SWI is called it will
 return an address of zero. Address returned will *always* be between or
 equal to the voice start address and the voice end address. This SWI is
 a very useful one for timing programs. By waiting for the address returned
 to become zero programs can wait till a particular sound sample has played.
 It must be noted that the update of this address is only at the end of 
 DMA buffer fills and thus will will jump up by the size of the DMA sound
 buffer instead of byte wise. It is,  however,  updated at the start of
 sound play immediately.

 DataVox_SetRepeat
 On Entry:-
 R0 DataChannel
 R1 Repeat Start address
 R2 Repeat End address
 On Exit:-
 R0,R1,R2 preserved
 Errors:-
 Bad Set Repeat Channel.
 Bad Set Repeat Memory - Start above End.
 Bad Set Repeat. Voice not active.
 Use:-
      This sets the Repeat address for the channel. Repeating occurs only
 when the timed flag is set and the voice is required to keep playing for
 longer than its play time by the time paramter sent via the sound command.
 When a repeat is neccessary play will start from the sections pointed to
 by these addresses. Note if play is set for reverse then any repeated
 sections will also be played in reverse.
      N.B. In an extension over older versions of DataPlay the Set Repeat
 SWI will no longer require that the addresses passed be inside those set
 by the Voice Start & End addresses. This is to allow you to perform
 buffering if you so wish. Read the description of the SWI ReadBufferFlag
 for more on this topic.

 DataVox_ReadRepeat
 On Entry:-
 R0 DataChannel
 On Exit:-
 R0 preserved
 R1 Repeat Start address
 R2 Repeat End address
 Errors:-
 Bad Read Repeat Channel.
 Use:-
      With this SWI you can read the repeat start and end addresses for the
 specified channel.

 DataVox_SetReverse
 On Entry:-
 R0 DataChannel
 R1 Bit Flag. 1 for reverse, 0 for normal play.
 On Exit:-
 R0,R1 preserved
 Errors:-
 Bad Set Reverse Channel.
 Use:-
         This sets the voice up to play the sound forwards or backwards. 
 Flipping this quickly will result in the voice changing directions as it
 plays and it can be used to do `scratch' style sounds.

 DataVox_ReadReverse
 On Entry:-
 R0 DataChannel
`On Exit:-
 R0 preserved
 R1 Status of reverse flag.
 Errors:-
 Bad Read Reverse Channel.
 Use:-
         This allows you to read whether a channel has been set to reverse
 play or not.

 DataVox_PitchToSample
 On Entry:-
 R0 Pitch
 R1 System Sample speed for pitch
 On Exit:-
 R0 Sample speed for pitch
 R1 preserved
 Errors:-
 Bad Pitch to Sample Pitch.
 Bad Pitch to Sample sample rate.
 Use:-
        This converts a pitch, with a given system speed in micro seconds,
 to a sample rate in micro seconds. When this is then fed to Sample to Pitch
 it gives you the system speed independance. It must be noted that this is a
 `lossy' conversion and exact pitching speeds will be lost. However most 
 times the approximation will be so close no discernable difference will
 be observed. Giving a system speed of zero will cause DataVox to use its
 copy of what the system speed is. Read the comments on the next SWI for
 an explanation as to why this is important.

 DataVox_SampleToPitch
 On Entry:-
 R0 Sample Speed (micro seconds)
 R1 System Speed (mirco seconds)
 On Exit:-
 R0 Pitch (-&7FFF - &7FFF)
 R1 preserved
 Errors:-
 Bad Sample Speed.
 Bad System Speed.
 Use:-
      This converts a system speed and sample speed pair into a sound pitch
 value that will cause the sound to be played correctly at that system speed.
 The conversion is what gives DataVox its system speed independance. If the
 system speed is 0 then DataVox will use its own copy of the current system
 speed. Because DataVox only updates its copy of what the System Speed is
 everytime a sound is played then it can get very out of sync with what
 the real system speed is. The upshot of this is that if you use the
 Sample to Pitch SWI to get the right pitch to feed into DataVox you
 could end up setting the pitch (correctly for the current system speed)
 but have DataVox readjust it incorrectly when it recalibrates to adjust
 to the `new' system speed. So this giving a system speed of zero to this
 SWI automatically fills in the system speed for you with DataVox's copy of 
 the system speed so that when it comes time to recalibrate DataVox will
 adjust everything correctly. When wanting to use DataVox's system speed
 independance it is reccomended that you use this SWI with the System Speed
 set to zero. Also setting R1 to zero recalibrates DataVox's copy of the
 System Speed.

 DataVox_Duplicate
 On Entry:-
 R0 Source DataChannel
 R1 Destination DataChannel
 On Exit:-
 R0,R1 preserved
 Errors:-
 Bad Duplicate Channel.
 Silly. Why are you trying to Duplicate to the same channel?
 Use:-
      This copies all the settings of one DataChannel to another. This 
 allows you to easily have channels that share the same piece of sampled
 data without much mucking about. Especially given the fact that this
 will always copy any new flags/settings I may add in the future.

 DataVox_Unset
 On Entry:-
 R0 DataChannel
 On Exit:-
 R0 Preserved
 Errors:-
 Bad Unset Channel.
 Use:-
      This completely clears and blanks a channel. Upon exit the selected
 channel will not have any settings at all having returned to the default
 state. If the channel being unset is playing then play will be terminated.

 DataVox_ConvertByte
 On Entry:-
 R0 Byte to Convert
 R1 Datatype the byte is. (0,1,2 or 3 as per DataVox_Type)
 R2 Type to convert the byte to. (0,1,2 or 3 as per DataVox_Type)
 On Exit:-
 R0 The Converted Byte
 R1,R2 preserved
 Errors:-
 I can't convert this. It isn't a byte!
 Bad Convert Byte Source type.
 Bad Convert Byte Convert to type.
 Use:-
      This SWI converts a byte from a particular data type to another type.
 It is perfectly acceptable to specify identical types in R1 & R2, all that
 will happen is that you get the same byte back again. Please Note converting
 between a Logarthimic DataType and a Linear DataType is *lossy*. The
 converted sound will replay almost identically but it will not convert back
 to its original form!

 DataVox_ReadBufferFlag
 On Entry:-
 R0 DataChannel to read
 On Exit:-
 R0 The Flag in the lowest bit.
 Errors:-
 Bad Read Buffer Flag Channel.
 Use:-
      Every time the Channel loads the Repeat start and end pointers this 
   flag will be toggled. Once the pointers are loaded they are stored in
   the Voices SCCB and so can be changed safely so that at next loading
   of them they can point to a new area. This SWI allows you to follow
   the loading of these pointers and if you wish to you can do some
   clever buffering for activities like playing samples from disk or
   playing compressed samples. *PLEASE NOTE* I make no guarantees that
   the bit you get back will be set or unset at any particular point
   in time. What I do guarantee is that the bit will change state as
   the pointers are loaded.

 DataVox_AllocateChannel
 On Entry:-
 R0 Unique key.
 On Exit:-
 R0 DataChannel assigned if succesful, 0 otherwise.
 Errors:-
 Bad Allocate Channel Key!
 Use:-
      This allows you to request a channel from DataVox that is free. If 
    there are no free channels then 0 is returned. No assumptions can be
    made about which channel will be handed back as this will vary from
    moment to moment depending on how many other applications are using
    the module. Also DataVox will not ensure that the channel is active
    or assigned to itself by the Sound System of the Arc. That is comp-
    letely the applications responsibility as there are too many variables
    for this module to cater for in a tidy fashion.
      The Unique key is the key needed to DeAllocate or Request this channel
    again. This key is needed to do the deallocate or request simply to
    allow the application that has been allocated the channel the knowledge
    that it is, as far as DataVox is concerned, the only owner of that
    channel. It also prevents careless applications from deallocating
    another applications channel. This is crucial to the safe multi-tasking
    of this module as it provides a measure of security allowing an 
    application to know for sure that it can do what it likes with the
    settings of a particular channel and not upset any other application's
    use of the module.
      Of course, due to other considerations, there is nothing to stop
    a badly programmed application from just using the SWI's to re-assign
    the other channels as it wishes so tasks *must* ensure their channel
    is set correctly before use. Whether this requires constant monitoring
    or simply checking just before use is application dependant. Due to
    problems of the ownership of channels by loading modules and maintaining
    backwards compatability this `hole' (More like a subway tunnel!) in
    channel security will *not* be fixed.

 DataVox_DeAllocateChannel
 On Entry:-
 R0 DataChannel to free
 R1 Unique key to channel
 On Exit:-
 R0 preserved
 R1 preserved
 Errors:-
 Bad DeAllocate Channel Channel.
 Bad DeAllocate Channel Key!
 Use:-
      This SWI will return, if the passed key is correct, the designated
    channel back to the free 'pool' of channels in DataVox allowing another
    application the chance to use it. This SWI will not disrupt the settings
    of the channel allowing applications to 'trade' channels if they so
    desire. Of course any such scheme must *not* rely totally on getting
    the channel and have code to cope with this contingency.

 DataVox_RequestChannel
 On Entry:-
 R0 DataChannel desired
 R1 Unique key for it
 On Exit:-
 R0 0 if request denied else preserved
 R1 preserved
 Errors:-
 Bad Request Channel Channel!
 Use:-
      If an application simply must have a particular channel then it can
    request for it. If the channel is free then the SWI will hand back the
    channel number and mark the channel as allocated with the key passed.
    If the channel is already allocated but the key passed matches the key
    given then the channel is handed back as DataVox considers that the
    application requesting it already `owns' it. Otherwise the request is
    denied by the SWI handing back a 0 as the channel. It is expected that
    applications be nice and actually respect this denial.

 DataVox_ChannelsFree
 On Entry:-
 R0 Undefined
 R1 Undefined
 On Exit:-
 R0 Number of unallocated channels available.
 R1 Number of allocated channels.
 Errors:-
 None
 Use:-
      What can be said about this one that isn't obvious? This returns the
    total number of free channels for use and the total number in use.

 DataVox_ConvertArea
 On Entry:-
 R0 Start Address
 R1 End Address
 R2 Datatype the byte is. (0,1,2 or 3 as per DataVox_Type)
 R3 Type to convert the byte to. (0,1,2 or 3 as per DataVox_Type)
    OR an address to a 256 byte lookup table.
 On Exit:-
 R0-R3 preserved
 Errors:-
 Your Start Address is below your End Address for conversion.
 Bad Convert Area Type.
 Bad Type to Convert Area to!
 Use:-
      This functions like Convert Byte only instead of converting a Byte
    it converts a chunk of memory at a go. This will be much faster then
    doing a byte by byte conversion of the area in your own code as it
    will not have to go through the high overhead that a SWI call entails
    for every byte.
      If you specify an address in R3 then the type in R2 is ignored and it
    is assumed that the lookup table is adjusted to cope with the datatype
    being converted. Please note R2 in this mode may be used at a later date
    by this code for a special meaning and should be by default set to zero
    in this conversion mode.
      The same comments about conversion restrictions in ConvertByte apply
    here.

 DataVox_ChannelFreeMap
 On Entry:-
 R0 undefined
 On Exit:-
 R0 Bitmap of the free channels.
 Errors:-
 None
 Use:-
      This SWI returns a bitmap of the free channels. If the bit is set then
    the channel is allocated else it is free. Bit Zero applies to channel 1,
    Bit One applies to channel 2 etc... I provided this SWI a) because I 
    needed it for one of my applications, b) to allow an application to
    easily monitor the free channels & c) I realised that I had not provided
    any way of non-destructively querying whether a channel is free or not.
    As there are currently only 8 channels supported by the VIDC then only
    the low eight bits will hold meaningful values. However the higher bits
    are by default cleared and no assumptions about their state should be
    made in case a future machine is released with more sound channels
    supported. As an aside you can easily find out the total number of 
    channels available by calling this SWI counting the number of bits set
    and the querying the number of channels free and totalling the two
    results. Of course it is far simpler to simply total the two registers
    passed back by ChannelsFree SWI. I consider it unlikely that more than
    32 channels will ever be supported by future hardware I just hope Acorn
    don't take this as a challenge and provide more than 32 channels! :-)

 DataVox_UpCallHandler
 On Entry:-
 R0 DataChannel desired
 R1 Address (absolute) or the routine to be called.(0 to deinstall a handler)
 R2 Private word to be passed to the routine.
 On Exit:-
 R0 preserved
 R1 preserved
 R2 preserved
 Errors:-
 Bad UpCall Handler Channel!
 Use:-
      This SWI provides a means by which special code can be added to DataVox
    to allow precise control over the order in which sample buffers are 
    played. The code is called under two circumstances - when a sound is
    started and when a buffer has been finished. Your code is expected to
    be :-
         a) FAST. Speed is *very* critical in this routine. Your code will
         called in IRQ mode with interupts shut off and so must be as fast
         as is possible to avoid problems. 
         b) always terminate. There must be absolutely no way in which your
         code cannot terminate. If your code does fail to terminate then 
         your machine will lock up! You have been warned...
         c) well behaved. Your code is being given access to the internal
         tables of DataVox and care must be taken not to damage any other
         channels table entries. Do *NOT* attempt to access any of the other
         channels data as this could cause your machine to crash.
         d) terminate cleanly. It is expected that your code generally
         obey the normal restrictions placed on interupt routines. Whatever
         you do do *not* turn interupts back on or exit back to DataVox
         in a processor mode different from that which DataVox called you
         in.

  The code calling mechanism is as follows.
   
  On Entry:-
   R0  reason for calling. (0-2 primary reason codes.)
   R1  pointer to word for the start of buffer address.
   R2  pointer to word for the end of buffer address.
   R3  channel number you are being called for. (0-7)
   R4  the private word passed to DataVox at installation.
   R5  pointer to the phase accumulator word used by the fill code.
   R6  #0 (Reason code 0 is an exception to this)
   R14 return address.
  On Exit:-
   R0  Return Code. (0 or 1)

    Registers R0-R6 can be corrupted and R14 contains the return address.
  The addresses passed in R1 & R2 are the addresses at which DataVox will
  *next* load the start & end addresses of the next buffer to be played.
  The passing of the channel number allows one chunk of code to handle
  mulitple channels simultaneously and accordingly your code must be
  re-entrant to handle this. (ie. keep your workspace seperate for each
  channel.) The private word passed in R4 is what you handed to DataVox
  when you installed the handler. This cannot be updated by any other means
  than reinstalling the handler. It is intended that routines put into
  modules use this word to point to their workspace... R5 is the phase
  pitch accumulator used by DataVox in fixed pitch play. Altering this
  word allows the UpCall code to alter the speed of sample play. The
  data format is that returned by the SWI "Sound_Pitch". IE a fixed point 32
  bit number with an 8 bit integer and 24 bits fractional data.
    The reason code passed gives you an indication of why your code is
  being called. 

  Code 0 indicates a start of sound synthesis/play. It is expected that 
         your code set itself to appropriate default values upon receiving
         this call. Also in this reason code call *alone* R6 is loaded
         with DataVox's copy of what the system speed in micro seconds
         is. It is expected that UpCall code use this to decide if
         certain pitch tables need recalibrating for the system speed.
  Code 1 indicates a normal play call. Under a reason 1 call the return code
         has effect allowing the upcalled code control over when play will
         halt. Returning a value of 1 indicates to DataVox that it should
         play another buffer. Returning 0 indicates an immediate stop in
         play.
  Code 2 indicates that a timed play is underway. In this mode DataVox will
         ignore the return code completely as it has control over when the
         sound play will halt. It is still valid to pass a return code back
         though (It just isn't used thats all....). In this mode looping
         from the start may be neccessary and your code should have some
         method of coping with this. Of course not altering the start &
         end addresses simply means the last buffer played will be played
         again....

 These three codes constitute the primary fill reason codes. All of these
 routines are *highly* speed critical and should not waste any time at all
 if possible! However the next few reasons codes are called in circumstances
 where speed is not so critical. Longer and more complex routines can be
 attempted here but again CallBack code writers should not waste time
 needlessly.

  Code 3 this is the system speed recalibration code. Your callback code
         will be called when DataVox detects a need to recalibrate the
         system speed and gives your code a chance to do likewise. It is
         expected that UpCall code will use this entry to recalibrate any
         internal pitch tables they have to the new system speed. It is 
         also expected that the code will adjust the phase accumulator
         word and DataVox will *assume* that the UpCall code will keep
         it correctly calibrated for the current system speed.
         Registers:-

         R0  #3
         R1  Old System Speed in micro seconds.
         R2  New System Speed in micro seconds.
         R3  Channel number (0-7) being recalibrated.
         R4  Private UpCall Data Word.
         R5  pointer to the phase accumulator word used by the fill code.
         R6  #0
        R14 return address.

         No return code is expected and any returned will be ignored.

  Code 4 this is the channel assignment entry code. DataVox is informing
         your code of the fact that another DataVox channel has been
         assigned to this code. It is expected that the code prepares
         itself in whatever ways are needed to play the new channel.
         Registers:-

         R0  #4
         R1  pointer to word for the start of buffer address.
         R2  pointer to word for the end of buffer address.
         R3  System Speed in micro seconds.
         R4  the private word passed to DataVox at installation.
         R5  pointer to the phase accumulator word used by the fill code.
         R6  #0
         R14 return address.

  Code 5 DataVox is requesting that you return in R1 the sequence data the
         upcall code is currently at. Obviously this is highly dependant on
         how your Upcall code is organised but should usually consist of the
         sequence number your code is up to. It is perfectly valid for UpCall
         code to ignore this call in which case an Automatic default will be
         assumed. If you are ignoring it then do not corrupt the registers
         at all.
         On Entry:-

         R0  #5
         R1  channel number (0-7)
         R2  #0
         R3  #0
         R4  #0
         R5  #0
         R6  #0
         R14 return address.

         On Exit:-
         
         R1  UpCall pause data.

  Code 6 Here DataVox is instructing the UpCall code to commence play from
         a specified point, passed in R1. It is expected that the UpCall
         code will restart play from the information passed to it. If the
         information is invalid it is fine for the UpCall code to ignore it
         and simply play as normal. The pause data should only have effect
         at the *next* start of sound play and should then be discarded.
         On Entry:-

         R0  #6
         R1  channel number (0-7)
         R2  UpCall pause word returned by reason code 5.
         R3  #0
         R4  #0
         R5  #0
         R6  #0
         R14 return address

 Your code should simply ignore any reason codes it doesn't understand and
 return back to DataVox doing nothing. If your code encounters an error it
 should simply unstack itself and exit cleanly rather than try to report
 an error. Any such attempts *will* fail.Also your code, if it is to be used
 in the Desktop, must always be paged in for DataVox to access. This means
 either that it must be stored in the RMA or that it only ever gets called
 while your application is currently paged in. And that about covers it.
 Please be very careful with this SWI as the potential for trouble with it
 is very high.

 DataVox_FlushKeys
 On Entry:-
 No parameters required.
 On Exit:-
 All registers preserved
 Errors:-
 none
 Use:-
      This SWI causes DataVox to DeAllocate all channels. This is a highly
    antisocial SWI and is provided only for development work. All finished
    applications should be tidy and be deallocating all their channels
    themselves anyway. However when developing new software channels can
    be left allocated causing DataVox to refuse to be killed. This means
    you have to hard reset your machine to get rid of it - very annoying.
    Under no circumstances should non-development code *ever* use this
    SWI. Use of this SWI totally destroys the multi-tasking coherency of
    DataVox and I will get extremely sad at code that does use it...

 DataVox_VoiceActive
 On Entry:-
 R0 0 to read 1 to read and set sound system.
 On Exit:-
 R0 Minimum number of sound channels needed active for DataVox.
 Errors:-
 none
 Use:-
      This SWI is provided to allow applications to keep the sound system at
    its minimum DMA level needed to support all assigned DataVox channels.
    If R0 is set to 1 on entry then not just will the minimum number be
    returned but DataVox will reconfigure the sound system to ensure the
    required number of voices is active. Please note it will *not* assign
    these channels to the DataVox voice - merely ensure that they are active
    for the application(s) to use.
      Applications that wish to be `social' should use this SWI to determine
    how many channels are needed and then query the sound system to see if
    sufficient channels are active already. If there are sufficient channels
    active then it should not alter the setting...

 DataVox_SystemSpeed
 On Entry:-
 R0 undefined
 On Exit:-
 R0 DataVox's copy of the system speed.
 Errors:-
 none
 Use:-
      The SWI returns to you DataVox's copy of what the system speed current-
    ly is. This is important because DataVox can be out of sync with what
    the system speed really is and an application needs to calculate some-
    thing like duration of play. This also will trigger a recalibration if one
    is needed.

 DataVox_Version
 On Entry:-
 R0 undefined
 On Exit:-
 R0 Version number of DataVox * 100.
 Errors:-
 none
 Use:-
      This SWI is for informational purposes to allow applications to 
    determine what facilities are available from DataVox. This allows
    well written applications to be able to use old versions of DataVox
    and only allow/use the extended features of new versions of DataVox
    if they are available.

 DataVox_SlaveChannel
 On Entry:-
 R0 Channel to be slaved.
 R1 Channel it is to be slaved to.
 On Exit:-
 R0,R1 preserved.
 Errors:-
 You can't slave the same channel to itself.
 Bad channel number to slave.
 Bad channel number to be slaved to.
 You cannot have a slaved channel as a master channel!
 Use:-
      This allows you to link channels together. Please note the master channel
    is not allowed to be slaved to another channel to prevent circular list
    problems. Please note you should not slave any channels you have not
    claimed using DataVox_AllocateChannel or RequestChannel! Please note due
    to the fact that the linking code is executed by callback there will be
    a delay between channels linked. If you do not want this delay then it is
    expected that you will drive the channels yourself in unlinked mode. This
    linking is purely for wimp applications and command line users to use in
    non critical sound applications. (Like playing back their favourite
    stereo beeps...Something I am rather partial to.)

 DataVox_ReadMaster
 On Entry:-
 R0 Channel to read.
 On Exit:-
 R0 Master of this channel. 0 for no master.
 Errors:-
 Bad channel to read the master of!
 Use:-
      This reads the channels master and reports it back to you. It is purely
    for informational purposes.

 DataVox_ReadUpCallStatus
 On Entry:-
 R0 Channel to read.
 On Exit:-
 R0 The UpCall status/pause word as returned.
 Errors:-
 Bad channel number to read.
 No UpCall code to interrogate!
 Use:-
      This issues a type 5 reason code call to the UpCall code on the
    specified channel. If there is no UpCall code on the channel then the
    routine will error and R0 will be in an undefined state. Please note it is
    the UpCall code's choice as to whether to ignore this reason code or not so
    the results returned are subject to what kind of UpCall code is present.

 DataVox_SetUpCallStatus
 On Entry:-
 R0 Channel to affect. 
 R1 UpCall status/pause word to write.
 On Exit:-
 Registers preserved.
 Errors:-
 Bad channel number to set.
 No UpCall code to call!
 Use:-
      Basically the opposite of a ReadUpCallStatus call this issues a type 6
    reason code call to the UpCall code on the specified channel. Again it is
    at the UpCall codes discretion to acknowledge this call or not.

 DataVox_AdjustMemory
 On Entry:-
 R0 DataChannel
 R1 DataStart
 R2 DataEnd
 On Exit:-
 R0 preserved
 R1 preserved
 R2 preserved
 Errors:-
 Bad Adjust Memory parameters.
 Use:-
      This functions in an identical manner to SetMemory. However it does not
    reset the datatype, reverse, pitch, upcall code or any of the other myriad
    settings bar that of the Repeat start and end addresses. It is intended
    that this be useful for sound players that can addresses frequently.

 DataVox_SetInternalPitch
 On Entry:-
 R0 DataChannel
 R1 32 bit fractional step.
 On Exit:-
 R0 preserved
 R1 preserved
 Errors:-
 Bad Set Internal Pitch parameters.
 Use:-
      This SWI allows the user to fine tune the sample replay stepping rate. It
   only has effect when the fixed pitching mode is active and is superceded by
   any SetMemory or SetPitch commands. The number passed in R1 should be
   treated as 32 bit fixed point number comprising 8 bits integer, 24 bits
   fractional numeric representation. Use of this SWI is depreciated but may be
   necessary under extreme circumstances, I would prefer applications to go
   through SetPitch wherever possible.

SWI Chunk numbering
===================

     Here is the table of DataVox's SWI chunk numbers on SWI names. Of course
 all names need to be preceded with `DataVox_' and the chunk range number
 is :- &44380

     Chunk # | SWI name
     --------+------------------
      0      | Type
      1      | Timed
      2      | Pitch
      3      | ReadPitch
      4      | ReadTimer
      5      | ReadType
      6      | SetMemory
      7      | ReadMemory
      8      | ReadAddress
      9      | SetRepeat
      10     | ReadRepeat
      11     | SetReverse
      12     | ReadReverse
      13     | PitchToSample
      14     | SampleToPitch
      15     | Duplicate
      16     | Unset
      17     | ConvertByte
      18     | ReadBufferFlag
      19     | AllocateChannel
      20     | DeAllocateChannel
      21     | RequestChannel
      22     | ChannelsFree
      23     | ConvertArea
      24     | ChannelFreeMap
      25     | UpCallHandler
      26     | FlushKeys
      27     | VoiceActive
      28     | SystemSpeed
      29     | Version
      30     | SlaveChannel
      31     | ReadMaster
      32     | ReadUpCallStatus
      33     | SetUpCallStatus
      34     | AdjustMemory
      35     | SetInternalPitch

Error Messages
==============

   The Error range begins at &806100, ends at &80613F, and here is the error
message list.

   Error # | Error Message
   --------+-------------------------------------------------------------
      0    | DataVox is still being used!
      1    | Unknown DataVox operation
      2    | Bad Address Channel.
      3    | Bad Timer parameters.
      4    | Bad Reverse parameters.
      5    | Bad Settype parameters.
      6    | Bad Set Memory parameters.
      7    | Bad Set Repeat Channel.
      8    | Bad Set Repeat Memory - Start above End.
      9    | Bad Set Repeat. Voice not active.
      10   | Bad Read Pitch Channel.
      11   | Bad Read Timer Channel.
      12   | Bad Read Reverse Channel.
      13   | Bad Read Type Channel.
      14   | Bad Pitch parameters.
      15   | Bad Read Memory Channel.
      16   | Bad Pitch to Sample Pitch.
      17   | Bad Pitch to Sample sample rate.
      18   | Bad Sample Speed.
      19   | Bad System Speed.
      20   | Bad Duplicate Channel.
      21   | Silly. Why are you trying to Duplicate to the same channel?
      22   | Bad Unset Channel.
      24   | I can't convert this. It isn't a byte!
      25   | Bad Convert Byte Source type.
      26   | Bad Convert Byte Convert to type.
      27   | Bad Read Buffer Flag Channel.
      28   | Bad DeAllocate Channel Channel.
      29   | Bad DeAllocate Channel Key!
      30   | Bad Request Channel Channel!
      31   | Your Start Address is above your End Address for conversion.
      32   | Bad Convert Area Type.
      33   | Bad Type to Convert Area to!
      34   | Bad UpCall Handler Channel!
      35   | Bad Allocate Channel Key!
      36   | Bad Request Channel Key!
      37   | You can't slave the same channel to itself.
      38   | Bad channel number to slave.
      39   | Bad channel number to be slaved to.
      40   | You cannot have a slaved channel as a master channel!
      41   | Bad channel to read the master of!
      42   | Bad channel number to read.
      43   | No Upcall code to interrogate!
      44   | Bad channel number to set.
      45   | No UpCall code to call!
      46   | Bad Adjust Memory parameters.


  Version History
  =========================================================================
  |Version | Comments.                                                    |
  =========================================================================
  | 1.00   | The first DataVox Module that supported only one file,timing |
  |        |   and data types. Released into the Public Domain.           |
  |        |   (07-Nov-1990)                                              |
  | 2.00   | Major re-write of code. Now it only plays chunks of memory   |
  |        |   and doesn't handle the loading of the data. (15-Jan-1991)  |
  | 2.01 - | Expanded support to handle eight independant channels from   |
  | 2.05   |   the one voice slot. Added the incidental code to control   |
  |        |   this new feature. Tidied up the Voice Code too!            |
  |        |   (16-Jan-1991 - 01-Feb-1991)                                |
  | 2.06   | Added the DataVoxStatus feature to show all the channels     |
  |        |   status. (02-Feb-1991)                                      |
  | 2.07   | Added the code to handle fixed pitch playing! Now all sounds |
  |        |   issued from the channel can be forced to play at a preset  |
  |        |   pitch. This in particular allows voices to be slaved to    |
  |        |   beep channel and for them to play correctly rather than    |
  |        |   at a too fast rate. (03-Feb-1991)                          |
  | 2.08   | Optimised the buffer fill code and corrected for a possible  |
  |        |   error to do with buffer exit fills. I suspect that I had   |
  |        |   made a small error in the flush code that resulted in the  |
  |        |   voice continuing to 'fill' the DMA buffer after the sound  |
  |        |   data had finished but filling it with 0's,thus resulting   |
  |        |   in no noise but heavy interupt overheads when there should |
  |        |   not have been... (24-Mar-1991)                             |
  | 2.09   | Added the DataVox_ReadAddress SWI at the request of Jason    |
  |        |   Williams. And saved on 28 bytes of size due to duplicated  |
  |        |   storage space that wasn't neccessary. (08-Jun-1991)        |
  | 2.10   | Corrected the timer flag algorithm to allow for repeated play|
  |        |   of a sample up to the time limit specified. (19-Aug-1991)  |
  | 2.11   | Allowed the addition of repeated play blocks. This allows    |
  |        |   samples to have a lead in and then a long repeated section |
  |        |   if so desired. Useful for coding music players.            |
  |        |   (19-Aug-1991)                                              |
  | 2.12   | Added reverse play code! Now you can play your samples either|
  |        |   way! The repeat loops even will be played in reverse.      |
  |        |   (20-Aug-1991)                                              |
  | 3.00   | Finally got the errors, with Julians help, out of the system |
  |        |   speed independance code. Now you can screw with the system |
  |        |   speed (Yuck!) and it will attempt to play the sample at the|
  |        |   right pitch. (26-Aug-1991)                                 |
  | 3.01   | Fixed a minor error in the Reverse play code. Now it reverses|
  |        |   properly if the sound is already playing. (28-Aug-1991)    |
  | 3.02   | Added the Unset and Duplicate code. Now you can very simply  |
  |        |   clear and copy the settings of any channel. (28-Aug-1991)  |
  | 3.03   | Fixed an Underflow/Overflow error with the conversion SWI's. |
  |        |   now only sensible values can be returned by it. Before     |
  |        |   values large and smaller than possible pitches were being  |
  |        |   returned. (28-Aug-1991)                                    |
  | 3.04   | Fixed an embarrising error in the `DataVox_SampleToPitch'    |
  |        |   SWI.. guess who got a compare the wrong way round...       |
  |        |   One of these days I guess I will just have to learn how to |
  |        |   code in assembler. :-). (28-Aug-1991)                      |
  | 3.05   | Removed an unnecessary SWI and upgraded two other SWI's to   |
  |        |   take its place. (29-Aug-1991)                              |
  | 3.06   | Fixed a bug in the smooth update code :- There wasn't any!   |
  |        |   This caused problems in the usage of volumes from &180 to  |
  |        |   &1FF. (29-Aug-1991)                                        |
  | 3.07   | Fixed a bug in the Set Repeat Code. (31-Aug-1991)            |
  | 3.08   | Fixed a minor bug in the Set Pitch Code. It wasn't clearing  |
  |        |   the sample rate table. Not harmful just untidy.            |
  |        |   (31-Aug-1991)                                              |
  | 3.09   | Added the ConvertByte SWI. My thanks to Edourard Poor &      |
  |        |   Julian Wright for the algorithm for converting Logarithmic |
  |        |   to Linear samples. (01-Sep-1991)                           |
  | 3.10   | Extended the SetRepeat SWI to allow for clever buffering     |
  |        |   tricks and added the ReadBufferFlag SWI to help with this. |
  |        |   (08-Sep-1991)                                              |
  | 3.11   | Added the extra SWI's for multitasking support. This now     |
  |        |   allows applications to `share' DataVox in a consistant     |
  |        |   way. (14-Sep-1991)                                         |
  | 3.12   | Added the ConvertArea SWI to allow fast Sample conversion    |
  |        |   when needed. (03-Oct-1991)                                 |
  | 3.13   | Added the ChannelFreeMap SWI to allow better channel         |
  |        |   allocation monitoring by tasks. (11-Oct-1991)              |
  | 3.14   | Adjusted the Type SWI to only have effect at the next start  |
  |        |   of play buffer fill. This cures a few problems with file   |
  |        |   overlay code... (12-Oct-1991)                              |
  | 3.15   | Added the UpCallHandler SWI. This now allows code quite fine |
  |        |   control over how sounds are played in DataVox.             |
  |        |   (15-Oct-1991)                                              |
  | 3.16   | Altered DataVox so that it now refuses to be killed till all |
  |        |   tasks using it have DeAllocated themselves. (15-Oct-1991)  |
  | 3.17   | Extended the kill system to allow the module to be RMTidied  |
  |        |   while tasks are using it while still remembering all the   |
  |        |   data. (16-Oct-1991)                                        |
  | 3.18   | Added the FlushKeys SWI for developers to use. This has      |
  |        |   become rather neccessary when DataVox refuses to die until |
  |        |   all channels are deallocated. (16-Oct-1991)                |
  | 3.19   | I quad word aligned the voice code to try and keep the IRQ   |
  |        |   load down as much as possible. DataVox does tend to suck   |
  |        |   bandwidth a bit... (17-Oct-1991)                           |
  | 3.20   | Further optimisations in the Fill code to keep the IRQ load  |
  |        |   down. (17-Oct-1991)                                        |
  | 3.21   | Fine tuning optimisation in the Fill code. Now the worst case|
  |        |   fill loop is five instructions per byte with the best case |
  |        |   four instructions per byte. This is about all the optimis- |
  |        |   ation I can make in the Fill code loop itself.             |
  |        |   (17-Oct-1991)                                              |
  | 3.22   | Extended the UpCall SWI to provide support for modules via   |
  |        |   a private word. (17-Oct-1991)                              |
  | 3.23   | Extended the ChannelsFree SWI to be slightly more detailed.  |
  |        |   (18-Oct-1991)                                              |
  | 3.24   | Extended the UpCall to pass the internal phase accumulator   |
  |        |   used by the fill code. (19-Oct-1991)                       |
  | 3.25   | Extended the Convert Area SWI to allow user defined lookup   |
  |        |   conversion tables. (25-Oct-1991)                           |
  | 3.26   | Added the VoiceActive SWI to allow applications to ensure the|
  |        |   sound system is sufficiently active to support all DataVox |
  |        |   assigned voices. (02-Nov-1991)                             |
  | 3.27   | Added two very small SWI's that allow a little more status   |
  |        |   reading of DataVox :- Version & SystemSpeed SWIs.          |
  |        |   (03-Nov-1991)                                              |
  | 3.28   | Corrected the Fill code to cope with timed play buffer sizes |
  |        |   smaller than the DMA buffer size. (03-Nov-1991)            |
  | 3.29   | Extended the Reason 0 (Init) UpCall code to load R6 with the |
  |        |   system sample speed. (04-Nov-1991)                         |
  | 3.30   | We have now acheived *full* system speed independance! Now   |
  |        |   the sound will adjust *with* the system if someone changes |
  |        |   it! (13-Nov-1991)                                          |
  | 3.31   | Mu Law datatype play has been added giving a fourth type that|
  |        |   DataVox understands. Now if only I had a sample or two to  |
  |        |   test these routines out on.... (14-Nov-1991)               |
  | 3.32   | Added a small bit to the pitch recalculation routines to help|
  |        |   prevent it being used when it is an undefined state. This  |
  |        |   should help with interupt usage of DataVox....             |
  |        |   (14-Nov-1991)                                              |
  | 3.33   | Fixed the recalibration code to prevent it being called with |
  |        |   invalid speeds and thus corrupting the pitch tables....    |
  |        |   (15-Nov-1991)                                              |
  | 3.34   | Corrected the Conversion code so conversion to and from Mulaw|
  |        |   now works properly. (16-Nov-1991)                          |
  | 3.35   | Added the SlaveChannel SWI and corrected a bug in the Reverse|
  |        |   SWI's code. (17-Nov-1991)                                  |
  | 3.36   | Fixed the Slaving code to work and updated the DataVoxStatus |
  |        |   command to cope with it. Added the ReadMaster SWI to allow |
  |        |   apps to monitor/control the slaving. (18-Nov-1991)         |
  | 3.37   | Fixed the VoiceActive SWI to correct a very embarrising      |
  |        |   error with it... It now works properly! (23-Nov-1991)      |
  | 3.38   | Adjusted the SampleToPitch SWI to recalibrate DataVox's      |
  |        |   idea of what the system speed is if R1 is 0 on Entry.      |
  |        |   (27-Nov-1991)                                              |
  | 3.39   | Fixed the Unset SWI to halt play if the channel being unset  |
  |        |   is playing at the time of being unset. (29-Nov-1991)       |
  | 3.40   | Corrected a couple of errors in the unset code introduced in |
  |        |   version 3.39. (1-Dec-1991)                                 |
  | 3.41   | Added two new reason codes to the UpCall system in prepera-  |
  |        |   tion for a standard UpCall file format. (12-Dec-1991)      |
  | 3.42   | Altered the fill code to fill in a byte wise fashion. This   |
  |        |   should considerably improve repeating play performance.    |
  |        |   (15-Dec-1991)                                              |
  | 3.43   | Corrected a few minor errors in a data-table and corrected an|
  |        |   error in the style of coding in error reporting...which    |
  |        |   saved some 200 bytes of space.... (16-Dec-1991)            |
  | 3.44   | Fixed errors in the newer Upcall code sections. (13-Jan-1992)|
  | 3.45   | 'Fixed' an error in the Upcall code system introduced in     |
  |        |   v3.42. However I am not happy with the fix as the code it  |
  |        |   'fixes' should work.... (16-Jan-1992)                      |
  | 3.46   | Corrected the Current Address routines to set the address up |
  |        |   at the start of sound play without waiting a DMA buffer    |
  |        |   fill. (20-Jan-1992)                                        |
  | 3.47   | Corrected an error in the Unset SWI routine that could have  |
  |        |   caused trouble.... Also modified it to not call its own SWI|
  |        |   routines via a SWI call but via a BL. This should improve  |
  |        |   its speed slightly. (2-Feb-1992)                           |
  | 3.48   | Various bug fixes to the UpCall code section. All now appears|
  |        |   to work as it should. (13-Feb-1992)                        |
  | 3.49   | Fixed a bug introduced by the UpCall code bug fixes.... Added|
  |        |   an upcall `pause` facility... (26-Feb-1992)                |
  | 3.50   | Received the SWI, Error and Message chunk allocations and    |
  |        |   coded them in. (18-Apr-1992)                               |
  | 3.51   | Fixed ConvertArea to full functionality. (14-Jun-1992)       |
  | 3.52   | Fixed the dynamic system speed recalibration to working order|
  |        |   after the additions made in v3.15 broke it... (Dang!)      |
  |        |   (28-Sep-1992)                                              |
  | 3.53   | Added to verify that DataVox is installed as a voice when    |
  |        |   AllocateChannel or RequestChannel is called. (09-Oct-1992) |
  | 3.54   | Added the AdjustMemory SWI with associated error message.    |
  |        |   Minor change to the Repeating pitch refresh. Major         |
  |        |   revamp of the play code to reduce bandwidth consumed by one|
  |        |   third. Also the play code now can stop and start on byte   |
  |        |   boundaries rather than word boundaries.(02-Nov-1992)       |
  | 3.55   | Added the SetInternalPitch SWI to allow for cases where      |
  |        |   extremely fine control of the replay rate is needed. Fixed |
  |        |   smooth update to not generate clicks when there is nothing |
  |        |   playing to update. Removed a redundant error message.      |
  |        |   Altered SampleToPitch to return negative pitches as needed.|
  |        |   SystemSpeed now recalibrates if needed. The internal fill  |
  |        |   code now uses 32bit fixed point values for sample replay   |
  |        |   improving the dynamic range coverage considerably.         |
  |        |   This version may break some early upcall code. Fixed the   |
  |        |   smooth update code to behave properly with respect to      |
  |        |   updating the pitch.(08-Nov-1992)                           |
  | 3.56   | Fixed the pitching commands to now accept pitches in the     |
  |        |   range -&7fff to &7fff. (26-Nov-1992)                       |
  | 3.57   | Fixed the Current Address update bug. (17-Apr-1993)          |
  | 3.58   | Fixed an error in the BufferFlag updating. Correction to     |
  |        |   buffer reloading code. (05-Jul-1993)                       |
  | 3.59   | Optimisations to the internal fill code. (2-Aug-1993)        |
  | 3.60   | Corrections to the Fill stopping code to prevent sample      |
  |        |   overflow. (7-Aug-1993)                                     |
  | 3.61   | Adjusted the repeating code to clear the phase accumulator.  |
  |        |   Corrected the fill code to correctly keep the phase        |
  |        |   accumulator across buffer fills. Altered the fill code to  |
  |        |   hopefully finally cure the overrun problem. A nice side    |
  |        |   effect is that CPU loading is now lowered somewhat.        |
  |        |   (12-Sep-1993)                                              |
  | 3.62   | Altered the fill code to reduce the size of it at the cost   |
  |        |   of one extra S cycle instruction. This allows a much       |
  |        |   unrolling of the loop allowing up to 64 bytes of the DMA   |
  |        |   buffer to be filled per loop pass. (compared to 16 bytes   |
  |        |   with previous versions) A major side effect of which is    |
  |        |   is further reduced CPU loading. (13-Sep-1993)              |
  | 3.63   | Fixed minor error with reverse code. (18-Oct-1993)           |
  | 3.64   | Corrected a few SWIs to return flags settings like they      |
  |        |   should. (14-Dec-1993)                                      |
  | 3.65   | Altered the GateOff code to return correct status bits.      |
  |        |   Altered the fill code to remove a register stacking - minor|
  |        |   efficiency stuff. (02-Jan-1994)                            |
  | 3.66   | Corrected a few stacking errors on some error returns.       |
  |        |   (20-Jan-1994)                                              |
  | 3.67   | Adjusted the pitch values to be more correct. (25-Jun-1994)  |
  | 3.68   | Altered ActiveVoices to ensure at least one channel is left  |
  |        |   active at all times. (27-Mar-1995)                         |
  =========================================================================